package com.nian.common.lock.zookeeper;

import com.nian.common.model.ServerResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.integration.zookeeper.lock.ZookeeperLockRegistry;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * 用途：
 * 开发：zhangmj
 * 日期：2020/4/13 0013 20:04
 */
@Slf4j
@Service
public class ZookeeperDistributedLock implements IZookeeperLock {

    @Autowired
    protected ZookeeperLockRegistry zookeeperLockRegistry;

    @Value("${zookeeper.distributedLock:false}")
    private boolean distributedLock;

    public final static String LOCKER_DEFAULT_NAME = "LOCKER_DEFAULT_NAME";

    public final static int LOCKER_DEFAULT_TIME = 10;

    @Override
    public ServerResponse lock(IZookeeperLockWorker worker) {
        return lock(LOCKER_DEFAULT_NAME, worker, LOCKER_DEFAULT_TIME);
    }

    @Override
    public ServerResponse lock(IZookeeperLockWorker worker, int second) {
        return lock(LOCKER_DEFAULT_NAME, worker, second);
    }

    @Override
    public ServerResponse lock(String lockName, IZookeeperLockWorker worker, int second) {
        Lock lock = null;
        try {
            if(distributedLock){
                lock = zookeeperLockRegistry.obtain(LOCKER_DEFAULT_NAME);
                log.info("{}: 锁地址：{}", Thread.currentThread().getName(), lock);
                boolean lockFlag = lock.tryLock(LOCKER_DEFAULT_TIME, TimeUnit.SECONDS);
                if(lockFlag){
                    return worker.invoke();
                }else {
                    return ServerResponse.createByErrorMessage("获取分布式锁失败!");
                }
            }
            return ServerResponse.createByErrorMessage("未启用分布式锁 zookeeper.distributedLock: true");
        }catch (Exception e){
            log.error("分布式锁处理错误:", e);
        }finally {
            try {
                if(lock != null){
                    log.info("{}: 释放锁地址：{}", Thread.currentThread().getName(), lock);
                    lock.unlock();
                }
            }catch (Exception e){
                log.error("释放锁异常:", e);
            }
        }
        return ServerResponse.createByError();
    }

}
